#include <iostream>
#include <vector>
#include <signal.h>
#include <unistd.h>

using namespace std;

#define MAX_SIG 31

static vector<int> sig_block = {2, 3}; // 要阻塞的信号都装在这个vector中

void Print_Pengding(const sigset_t &pengding)
{
    // 打印
    for (int i = MAX_SIG; i >= 1; i--)
    {
        // 判断pengding信号集第i位的的比特位是否为1
        if (sigismember(&pengding, i))
            cout << "1";
        else
            cout << "0";
    }
    cout << "\n";
}

void handler(int signo)
{
    cout << signo << "号信号被捕获" << endl;
}

int main()
{
    // 对sig_block内的信号进行自定义捕获
    for (auto &signo : sig_block)
        signal(signo, handler);

    // 1. 初始化信号集
    sigset_t block, oblock, pending;
    sigemptyset(&block);
    sigemptyset(&oblock);
    sigemptyset(&pending);

    // 2. 添加要阻塞的信号
    for (auto &sig : sig_block)
        sigaddset(&block, sig);

    // 3. 将要阻塞的信号添加到当前进程的block中
    sigprocmask(SIG_SETMASK, &block, &oblock);

    // 4. 不断获取当前进程的pending信号集
    int cnt = 10;
    while (true)
    {
        // 4,1 初始化
        sigemptyset(&pending);
        // 4.2 获取当前进程pengding
        sigpending(&pending);
        // 4.3 打印pending信号集
        Print_Pengding(pending);
        // 慢一点
        sleep(1);
        if (cnt-- == 0)
        {
            cout << "解除对信号的屏蔽\n";
            // 将修改之前的信号集设置到当前进程
            sigprocmask(SIG_SETMASK, &oblock, &block); // 一旦解除对信号的屏蔽，OS至少会立马处理一个信号！
            cout << "解除完毕\n";
            // 如果想要sig_block内的信号重新被阻塞，这里可以设置
            cout << "重新设置阻塞\n";
            sigprocmask(SIG_SETMASK, &block, &oblock); // 将之前被解除阻塞的信号重新设置阻塞
            cnt = 10;                                  // 重置，再来10s之后，再次进入该分支
        }
    }

    return 0;
}

